//样例
let exampleItem=[
    {
        sets:"{1,2,3,4,6,12}",
        relations:"{(1,1),(1,2),(1,3),(1,4),(1,6),(1,12),(2,2),(2,4),(2,6),(2,12),(3,3),(3,6),(3,12),(4,4),(4,12),(6,6),(6,12),(12,12)}"
    },
    {
        sets:"{a,b,c,d,e,f,g,h,i,j}",
        relations:"{(a,a),(b,b),(c,c),(d,d),(e,e),(f,f),(g,g),(h,h),(i,i),(j,j),(a,c),(a,e),(a,h),(a,d),(a,g),(a,i),(a,j),(b,c),(b,e),(b,h),(b,d),(b,g),(b,i),(b,j),(c,d),(c,e),(c,h),(c,g),(c,i),(c,j),(d,g),(d,i),(e,h),(e,j),(f,h),(f,j),(h,j),(g,i)}"
    },
    {
        sets:"{2,3,5,7,14,15,21}",
        relations:"{(2,2),(3,3),(5,5),(7,7),(14,14),(21,21),(2,14),(7,14),(7,21),(3,21),(3,15),(15,15)}"
    },
    {
        sets:"{1,2,3,4}",
        relations:"{(1,1),(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,3),(3,4),(4,4)}"
    },
    {
        sets:"{a,b,c,d,e,f,g,h}",
        relations:"{(a,a),(b,b),(c,c),(d,d),(e,e),(f,f),(g,g),(h,h),(b,d),(b,e),(b,f),(c,d),(c,e),(c,f),(d,f),(e,f),(g,h)}"
    },
    {
        sets:"{1,2,3,4,12}",
        relations:"{(1,1),(2,2),(3,3),(4,4),(12,12),(1,2),(1,3),(1,4),(1,12),(2,4),(3,12),(2,12),(4,12)}"
    }
]
//{(a,a),(b,b),(c,c),(d,d),(e,e),(f,f),(g,g),(h,h),(i,i),(j,j),(a,c),(a,e),(a,h),(a,d),(a,g),(a,i),(a,j),(b,c),(b,e),(b,h),(b,d),(b,g),(b,i),(b,j),(c,d),(c,e),(c,h),(c,d),(c,g),(c,i),(c,j),(d,g),(d,i),(e,h),(e,j),(f,h),(f,j),(h,j),(g,i)}
function getOption(graphInfo){
//给节点设置样式
    let nodes=graphInfo['nodes'];
    let links=graphInfo['links'];
    //console.log(links);
//设置option样式
    return {
        title: {
            text: title,
            left: 'center',
            textStyle:{
                fontSize:20
            },
            bottom:20
        },
        tooltip: {
            trigger: 'item'
        },
        autoCurveness:true,
        backgroundColor:'white',
        roam: true,
        series: [
            {
                type: 'graph',
                layout: 'none',
                ribbonType: false,
                symbol: "circle",
                edgeSymbol:['none', 'none'],
                symbolSize: 27,
                edgeSymbolSize: 10,
                nodes: nodes,
                links: links,
                label: {
                    normal: {
                        show: true
                    }
                },
                draggable:true
            }
        ]
    };
}
function nodeStyle(title,x,y){
   return  { 
       name: title,
       x:x,y:y,
       itemStyle: {borderColor: 'black',color:'white',borderWidth: 3},
       label:{
           show:true,
           position:'inside',
           fontSize:15,
           color:'black',
           fontWeight:'bold'
        }
    }
}
function edgeStyle(selectNode){
    return {
        source: selectNode[0],
        target: selectNode[1],
        value:100,
        lineStyle: {
            width: 5,
            color: '#000',
            type:'solid',
            opacity:0.8,
            ignoreForceLayout:true
        }
    };
}
function initData(){
    nodes=[],links=[],option={},title=""; 
    sets=[],relations=[];
}
let nodes=[],links=[],option={},matrix=[],title="",myChart,covList=[],sets=[],relations=[];;
var app=new Vue({
    el:"#app",
    data:{
        sets:"",
        relations:"",
        matrixs:'',
        isShowMatrix:false,
        condition1:'',
        condition2:'',
        condition3:'',
        result:'',
        setList:[],
        quotientSet:"",
        isShowResult:false,
        nodeList:[],
        COVA:"",
        examples:[1,2,3,4,5,6],
        cSets:"",
        jiMax:"",jiMin:"",max:"",min:"",top:"",bottom:"",topMin:"",bottomMax:"",
        showElement:false,
        covList:[]
    },
    methods: {
        relationShow(){
            relations=[];
            matrix=[];
            //字符串处理
            console.log(this.sets);
            console.log(this.relations);
            //检查格式是否正确
            try{
                var reg = RegExp(/^{[a-zA-Z0-9]+(,([a-zA-Z0-9]+))+}$/);
                if(!this.sets.match(reg)){
                    modalApp.modalAlert("集合格式输入不正确");return;
                }
                var reg1=RegExp(/^{\([a-zA-Z0-9]+,[a-zA-Z0-9]+\)(,\([a-zA-Z0-9]+,[a-zA-Z0-9]+\))+}$/);
                if(!this.relations.match(reg1)){
                    modalApp.modalAlert("关系格式输入不正确");return;
                }
                sets=this.sets.slice(1,this.sets.length-1).split(',');
                console.log(sets);
                let rel=this.relations.slice(1,this.relations.length-1).split(',');
                for(let i=0;i<rel.length;i=i+2){
                    relations.push({
                        a1:rel[i].slice(1),
                        a2:rel[i+1].slice(0,rel[i+1].length-1),
                    });
                }
                console.log(relations);
                //如果关系中的点在集合中不存在则 报错
                for(let i=0;i<sets.length;i++){
                    matrix[i]=[];
                    for(let j=0;j<sets.length;j++){
                        matrix[i][j]=0;
                    }
                }
                for(let i=0;i<relations.length;i++){
                    let t1=sets.indexOf(relations[i].a1);
                    let t2=sets.indexOf(relations[i].a2);
                    if(t1!=-1&&t2!=-1){
                        matrix[t1][t2]=1;
                    }
                    else{
                        modalApp.modalAlert("关系中的点在集合中不存在");return;
                    }
                }
                let num=0;
                //判断是否自反
                if(!selfReflexivity()){
                    this.condition1="不具有自反性"
                }
                else{
                    this.condition1="具有自反性";
                    num++;
                }
                //判断是否对称性
                if(!antiSymmetry()){
                    this.condition2="不具有反对称性"
                }
                else{
                    this.condition2="具有反对称性";
                    num++;
                }
                //判断是否传递性
                if(!Transitive()){
                    this.condition3="不具有传递性"
                }
                else{
                    this.condition3="具有传递性";
                    num++;
                }
                if(num==3) this.result="是偏序关系"
                else this.result="不是偏序关系"
            }catch(e){
                console.log(e);
                return;
            }
        },
        equalityShow(){
            this.showElement=false;
            this.isShowMatrix=false;
            this.isShowResult=false;
            matrix=[];relations=[];
            covList=[];
            nodes=[],links=[],option={},title=""; 
            //检查格式是否正确
            try{
                var reg = RegExp(/^{[a-zA-Z0-9]+(,([a-zA-Z0-9]+))*}$/);
                if(!this.sets.match(reg)){
                    modalApp.modalAlert("集合格式输入不正确");return;
                }
                var reg1=RegExp(/^{\([a-zA-Z0-9]+,[a-zA-Z0-9]+\)(,\([a-zA-Z0-9]+,[a-zA-Z0-9]+\))*}$/);
                if(!this.relations.match(reg1)){
                    modalApp.modalAlert("关系格式输入不正确");return;
                }
                sets=this.sets.slice(1,this.sets.length-1).split(',');
                
                let rel=this.relations.slice(1,this.relations.length-1).split(',');
                for(let i=0;i<rel.length;i=i+2){
                    relations.push({
                        a1:rel[i].slice(1),
                        a2:rel[i+1].slice(0,rel[i+1].length-1),
                    });
                }
                for(let i=0;i<sets.length;i++){
                    matrix[i]=[];
                    for(let j=0;j<sets.length;j++){
                        matrix[i][j]=0;
                    }
                }
                
                for(let i=0;i<relations.length;i++){
                    let t1=sets.indexOf(relations[i].a1);
                    let t2=sets.indexOf(relations[i].a2);
                    if(t1!=-1&&t2!=-1){
                        matrix[t1][t2]=1;
                    }
                    else{
                        modalApp.modalAlert("关系中的点在集合中不存在");return;
                    }
                }
                
                this.isShowResult=true;
                let nodess=covNode();
                this.COVA=nodess.covStr;
                let nodeList=nodess.nodeLevel;
                let m=nodess.matrix;
                //哈斯图构建算法
                //let nodeList=Hassee(sets,relations);
                //covList=[];
                for(let i=0;i<nodeList.length-1;i++){
                    for(let j=0;j<nodeList[i].length;j++){
                        let o=1;
                        while((i+o)<nodeList.length){
                          for(let k=0;k<nodeList[i+o].length;k++){
                            if(m[sets.indexOf(nodeList[i][j])][sets.indexOf(nodeList[i+o][k])]==1) {
                                links.push(edgeStyle([nodeList[i][j],nodeList[i+o][k]]));
                                covList.push({s:nodeList[i+o][k],t:nodeList[i][j]});
                            }
                          }
                          o++;
                        }
                        
                    }
                }
                 //构建哈斯图 对于没有连接线的点单独排列
                for(let i=0;i<nodeList.length;i++){
                    let obj=sortArr(nodeList[i]);
                    nodeList[i]=obj.arr;
                    let len=obj.len;
                    for(let j=0;j<nodeList[i].length;j++){
                        if(j<len)
                            nodes.push(nodeStyle(nodeList[i][j],Math.floor(100/(len+1))*(j+1),100-10*(i+1)))
                        else{
                            nodes.push(nodeStyle(nodeList[i][j],100+10*(j-len+1),100-10*(i+1)))
                        }
                    }
                }
                console.log(nodes);
                console.log(links);
                console.log(m);
                let jsonData={"nodes":nodes,"links":links}
                option=getOption(jsonData);
                this.$nextTick(function () {
                    myChart = echarts.init(document.getElementById('echartsDiv'));
                    myChart.setOption(option);
                });
                //哈斯图步骤 
                this.nodeList=nodeList;
                modalApp.modalAlert("哈斯图生成成功!"); 
            }catch(e){
                console.log(e);
                return;
            }
        },
        showExample(index){
            initData();
            console.log(index);
            this.showElement=false;
            this.isShowMatrix=false;
            this.isShowResult=false;
            this.condition1='';
            this.condition2='';
            this.condition3='';
            this.result='';
            this.sets=exampleItem[index].sets;
            this.relations=exampleItem[index].relations;
        },
        DataShow(){
            try{
                let cSets=this.cSets;//B子集合
                let sets=this.sets;//A集合
                let Cmatrix=[];  //B子集邻接
                let matrix=[];   //A集合邻接
                let relations=[]; //关系集
                var reg = RegExp(/^{[a-zA-Z0-9]+(,([a-zA-Z0-9]+))*}$/);
                if(!cSets.match(reg)){
                    modalApp.modalAlert("集合格式输入不正确");return;
                }
                console.log(this.sets);
                sets=sets.slice(1,sets.length-1).split(',');
                cSets=cSets.slice(1,cSets.length-1).split(',');
                console.log(cSets);
                for(let i=0;i<cSets.length;i++){
                    if(sets.indexOf(cSets[i])==-1){
                        modalApp.modalAlert("子集输入错误");return;
                    }
                }
                let rel=this.relations.slice(1,this.relations.length-1).split(',');
                for(let i=0;i<rel.length;i=i+2){
                    relations.push({
                        a1:rel[i].slice(1),
                        a2:rel[i+1].slice(0,rel[i+1].length-1),
                    });
                }
                //A集合邻接
                for(let i=0;i<sets.length;i++){
                    matrix[i]=[];
                    for(let j=0;j<sets.length;j++){
                        matrix[i][j]=0;
                    }
                }      
                for(let i=0;i<relations.length;i++){
                    let t1=sets.indexOf(relations[i].a1);
                    let t2=sets.indexOf(relations[i].a2);
                    if(t1!=-1&&t2!=-1){
                        matrix[t1][t2]=1;
                    }
                }
                //子集的邻接
                for(let i=0;i<cSets.length;i++){
                    Cmatrix[i]=[];
                    for(let j=0;j<cSets.length;j++){
                        Cmatrix[i][j]=0;
                    }
                }      
                for(let i=0;i<relations.length;i++){
                    let t1=cSets.indexOf(relations[i].a1);
                    let t2=cSets.indexOf(relations[i].a2);
                    if(t1!=-1&&t2!=-1){
                        let t11=sets.indexOf(cSets[t1]);
                        let t22=sets.indexOf(cSets[t2]);
                        Cmatrix[t1][t2]=matrix[t11][t22];
                        if(t1==t2) Cmatrix[t1][t2]=1;
                    }
                }
                
                let jiMax=[],jiMin=[],max="",min="",top=[],bottom=[],topMin="",bottomMax="";
                let nodeList=this.nodeList;
                console.log(matrix);
                console.log(Cmatrix);
                //极大元极小元 最大元最小元
                let i=0,j=0;
                for(i=0;i<Cmatrix.length;i++){
                    for(j=0;j<Cmatrix.length;j++){
                        if(i!=j){
                            if(Cmatrix[i][j]!=0) break;
                        } 
                    }
                    if(j==Cmatrix.length) jiMax.push(cSets[i]);
                }
                if(jiMax.length==0) jiMax="无极大元";

                for(i=0;i<Cmatrix.length;i++){
                    for(j=0;j<Cmatrix.length;j++){
                        if(i!=j){
                            if(Cmatrix[j][i]!=0) break;
                        }
                    }
                    if(j==Cmatrix.length) jiMin.push(cSets[i]);
                }
                if(jiMin.length==0) jiMin="无极小元";

                for(i=0;i<Cmatrix.length;i++){
                    for(j=0;j<Cmatrix.length;j++){
                        if(Cmatrix[j][i]!=1) break;
                    }
                    if(j==Cmatrix.length) break;
                }
                if(i==Cmatrix.length) max="无最大元";
                else max=cSets[i];

                for(i=0;i<Cmatrix.length;i++){
                    for(j=0;j<Cmatrix.length;j++){
                        if(Cmatrix[i][j]!=1) break;
                    }
                    if(j==Cmatrix.length) break;
                }
                if(i==Cmatrix.length) min="无最小元";
                else min=cSets[i];

                for(i=0;i<matrix.length;i++){
                    for(j=0;j<Cmatrix.length;j++){
                        let j1=sets.indexOf(cSets[j]);
                        if(matrix[j1][i]!=1) break;
                    }
                    if(j==Cmatrix.length) top.push(sets[i]);
                }
                if(top.length==0) {top="无上界";topMin="无上确界";}
                else{
                    for(i=0;i<top.length;i++){
                        for(j=0;j<top.length;j++){
                            let i1=sets.indexOf(top[i]);
                            let j1=sets.indexOf(top[j]);
                            if(matrix[i1][j1]!=1) break;
                        }
                        if(j==top.length){
                            topMin=top[i];break;
                        }
                    }
                    if(i==top.length) topMin="无上确界";
                }

                for(i=0;i<matrix.length;i++){
                    for(j=0;j<Cmatrix.length;j++){
                        let j1=sets.indexOf(cSets[j]);
                        console.log(matrix[i][j1]);
                        if(matrix[i][j1]!=1) break;
                    }
                    if(j==Cmatrix.length) bottom.push(sets[i]);
                }
                if(bottom.length==0) {bottom="无下界";bottomMax="无下确界";}
                else{
                    for(i=0;i<bottom.length;i++){
                        for(j=0;j<bottom.length;j++){
                            let i1=sets.indexOf(bottom[i]);
                            let j1=sets.indexOf(bottom[j]);
                            if(matrix[j1][i1]!=1) break;
                        }
                        if(j==bottom.length){
                            bottomMax=bottom[i];break;
                        }
                    }
                    if(i==bottom.length) bottomMax="无下确界";
                }
                

                this.jiMax=jiMax.toString();
                this.jiMin=jiMin.toString();
                this.max=max;
                this.min=min;
                this.top=top.toString();
                this.bottom=bottom.toString();
                this.topMin=topMin;
                this.bottomMax=bottomMax;
                this.showElement=true;
            }catch(e){
                console.log(e);
            }
        }
    },
})
var modalApp=new Vue({
    el:"#myModal1",
    data:{
        message:""
    },
    methods:{
        modalAlert(str){
            this.message=str;
            $('#myModal1').modal('toggle');
        }
    }
})

//自反性
function selfReflexivity(){
    for(let i=0;i<matrix.length;i++){
        if(matrix[i][i]!=1) return false
    }
    return true;
}
//反对称性
function antiSymmetry(){
     for(let i=0;i<matrix.length;i++){
        for(let j=i+1;j<matrix[i].length;j++){
            if(matrix[i][j]==1&&(matrix[i][j]==matrix[j][i])) return false
        }
    }
    return true;
}
//传递性
function Transitive(){
    //传递性
    let p = 0,x=matrix.length,y=matrix.length;
    for(let i = 0 ; i < x ; i++)
    {
        for(let j = 0 ; j < y ; j++)
        {
            if( 1 == matrix[i][j] )
            {
                for(let k = 0 ; k < y ; k++)
                {
                    if( 1 == matrix[j][k] && 1 != matrix[i][k] )
                    {
                        p = 1;
                        break;
                    }
                }
            }
        }
    }
    if(p) return false;
    else return true;
}
function Hassee(A0,R0){
    let A1=[],R1=[],node=[],i=0;
    R0=removeEqual(R0);
    //console.log(R0);
    while(A0.length>0){
        A1=getRightSets(R0);
        //console.log(A0);
        //console.log(A1);
        node[i]=setsSubtract(A0,A1);
        //console.log(node[i]);
        R1=removeNodeR(node[i],R0);
        //console.log(R1);
        A0=copySR(A1);
        R0=copySR(R1);
        i++;
    }
    console.log(node);
    //对分层的节点再进一步处理 若有孤立点则判断是否有隔层的连线
    return  node;
}
//除去自反性
function removeEqual(R0){
    let R1=[];
    for(let i=0;i<R0.length;i++){
        if(R0[i].a1!=R0[i].a2){
            R1.push(R0[i]);
        }
    }
    return R1;
}
//获取关系上值域上的所有点的集合
function getRightSets(R){
    let A1=[]
    for(let i=0;i<R.length;i++){
        if(A1.indexOf(R[i].a2)==-1){
            A1.push(R[i].a2);
        }
    }
    return A1;
}
//集合减法
function setsSubtract(A0,A1){
    let sub=[];
    for(let i=0;i<A0.length;i++){
        if(A1.indexOf(A0[i])==-1) sub.push(A0[i]);
    }
    return sub;
}
//去除与点有关的关系
function removeNodeR(node,R0){
    let R=[];
    for(let j=0;j<R0.length;j++){
        if(node.indexOf(R0[j].a1)==-1&&R.indexOf(R0[j])==-1) R.push(R0[j]);
    }
    return R;
}
//集合拷贝
function copySR(A1){
    let A0=[];
    for(let i=0;i<A1.length;i++){
        A0.push(A1[i]);
    }
    return A0;
}
//对于没有连接线的点单独排列
function sortArr(arr){
    let arr1=[],arr2=[];
    for(let i=0;i<arr.length;i++){
        if(findNode(arr[i])) arr1.push(arr[i]);
        else arr2.push(arr[i]);
    }
    return {len:arr1.length,arr:arr1.concat(arr2)};
}
function findNode(tag){
    for(let i=0;i<links.length;i++){
        if(tag==links[i].source||tag==links[i].target){
            return true;
        }
    }
    return false;
}
function isCov(s,t){
   for(let i=0;i<covList.length;i++){
       if(covList[i].s==s&&covList[i].t==t)return true;
   }
   return false;
}
function covNode(){
    let l=matrix.length;
    let m=[];
    let nodeList=[];
    let nodes=[];
    for(let i=0;i<l;i++){
        m[i]=[];nodes.push(sets[i]);
        for(let j=0;j<l;j++){
            m[i][j]=matrix[i][j];
        }
    }
    for(let i=0;i<l;i++){
        for(let j=0;j<l;j++){
            if(m[i][j]==1){
                for(let k=0;k<l;k++){
                    if(m[j][k]==1&&i!=j&&j!=k) m[i][k]=0;
                }
            }
        }
        m[i][i]=0;
    }
    let covStr="{"
    for(let i=0;i<m.length;i++){
        for(let j=0;j<m.length;j++){
            if(m[i][j]==1){
                if(covStr=="{") covStr+=`(${setMy(i)},${setMy(j)})`;
                else covStr+=`(${setMy(i)},${setMy(j)})`;
                nodeList.push({s:setMy(i),t:setMy(j)});
            }
        }
    }
    covStr+="}";
    console.log(nodeList);
    let nodeLevel=[];
    let i=0,j=0,k=0,flag=true;
    while(nodeList.length!=0&&flag){
        flag=false;
        for(i=0;i<nodes.length;i++){
            
            for(j=0;j<nodeList.length;j++){
                if(nodeList[j].t==nodes[i]) break;
            }
            if(j==nodeList.length) {
                if(nodeLevel[k]==undefined) nodeLevel[k]=[];
                nodeLevel[k].push(nodes[i]);
                nodes.splice(i,1);
                i--;
                flag=true;
            }
        }
        
        for(i=0;i<nodeLevel[k].length;i++){
            for(j=0;j<nodeList.length;j++){
                if(nodeList[j].s==nodeLevel[k][i]){
                    nodeList.splice(j,1);j--
                }
            }
        }
        k++;
    }
    if(nodes.length!=0){
        nodeLevel[k]=nodes;
    }
    console.log(nodeLevel)
    console.log(covStr);
    console.log(m);
    return {"covStr":covStr,"matrix":m,"nodeLevel":nodeLevel}
}
function setMy(i){
    return sets[i];
}